import './BasicLayout.less';

import React from 'react';

// 直接引用ProLayout的接口，今后紧跟Pro的规范
import type { BasicLayoutProps } from '@ant-design/pro-layout';
import type { MenuDataItem } from '@ant-design/pro-layout/lib/typings';

// ant-design的工具类
import getMenuData from '@ant-design/pro-layout/lib/utils/getMenuData';
// import useCurrentMenuLayoutProps from '@ant-design/pro-layout/lib/utils/useCurrentMenuLayoutProps';

// 引入ant-design组件
import { Layout } from 'antd';

import { useDeepCompareEffect } from '@ant-design/pro-utils';

// 引入umi组件
import { getMatchMenu } from '@umijs/route-utils';
import { useIntl, useModel } from 'umi';

// 第三方组件
import { stringify } from 'use-json-comparison';
// import Omit from 'omit.js';
import useMergedState from 'rc-util/lib/hooks/useMergedState';
// import useAntdMediaQuery from 'use-media-antd-query';

// 自己定义的组件
import MainSider from './MainSider';
import SubSider from './SubSider';
import HeadderContent from './HeaderContent';
import MyFooter from '@/components/Footer';
import RightContent from '@/components/RightContent';

const { Footer, Content } = Layout;

/**
 * 🌃 Powerful and easy to use beautiful layout
 * 🏄‍ Support multiple topics and layout types
 * @param props
 */
const BasicLayout: React.FC<BasicLayoutProps> = (props) => {
  const { children, location = { pathname: '/' }, route, menu } = props;
  // const context = useContext(ConfigProvider.ConfigContext);
  // const prefixCls = props.prefixCls ?? context.getPrefixCls('pro');

  const intl = useIntl();
  const { formatMessage } = intl;

  /**
   * 重新得到菜单
   */
  const { initialState } = useModel('@@initialState');

  // authorities从数据库中得到的权限，例如：/welcome,/welcome/home,/goods,/goods/class
  // 现在要在首尾添加逗号，因为下面要进行检索是按照：，/welcome，
  const authorities: string = `,${initialState?.currentUser?.authorities || ''},`;
  const isSuper = initialState?.currentUser?.user.adminIsSuper;

  // 递归函数
  const fillTree = (parentNode: MenuDataItem, nodes: MenuDataItem[]) => {
    if (!parentNode.children) {
      // eslint-disable-next-line no-param-reassign
      parentNode.children = [];
    }
    for (let i = 0; i < nodes.length; i += 1) {
      const node = nodes[i];
      // node.path中有的字符，需要截取掉
      const tempPath = node.path?.substring('/admin'.length);
      // 在authorities中查找是否有这个菜单，这里添加了两个逗号包裹，这样不容易查错
      if (authorities.indexOf(`,${tempPath},`) >= 0) {
        const addNode: MenuDataItem = {
          path: node.path,
          icon: node.icon,
          name: node.name,
          locale: node.locale,
          children: [],
        };

        // 递归调用下一级菜单
        if (node.children && node.children.length > 0) {
          fillTree(addNode, node.children);
        }

        // 填入到要返回的数组中
        parentNode.children.push(addNode);
      }
    }
  };

  type menuDataRenderRen = ((menuData: MenuDataItem[]) => MenuDataItem[]) | undefined;
  let menuDataRender: menuDataRenderRen;

  if (!isSuper) {
    menuDataRender = (params: MenuDataItem[]) => {
      const rootNode: MenuDataItem = { children: [], path: '/' };
      // 填充菜单
      fillTree(rootNode, params);
      return rootNode.children;
    };
  }

  /**
   * 得到菜单信息
   */
  const [menuInfoData, setMenuInfoData] = useMergedState<{
    breadcrumb: {
      [key: string]: MenuDataItem;
    };
    breadcrumbMap?: Map<string, MenuDataItem>;
    menuData?: MenuDataItem[];
  }>(() => getMenuData(route?.routes || [], menu, formatMessage, menuDataRender));

  // 得到当前的选择的菜单
  const { breadcrumbMap, menuData = [] } = menuInfoData;
  const matchMenus = getMatchMenu(location.pathname || '/', menuData, true);
  const matchMenuKeys = Array.from(new Set(matchMenus.map((item) => item.key || item.path || '')));

  // 当前选中的menu，一般不会为空
  /*
  const currentMenu = (matchMenus[matchMenus.length - 1] || {}) as ProSettings & MenuDataItem;
  const currentMenuLayoutProps = useCurrentMenuLayoutProps(currentMenu);
  const { fixSiderbar, navTheme, layout: defaultPropsLayout, ...rest } = {
    ...props,
    ...currentMenuLayoutProps,
  };
  */

  /**
   *  如果 menuRender 不存在，可以做一下性能优化
   *  只要 routers 没有更新就不需要重新计算
   */
  useDeepCompareEffect(() => {
    if (menu?.loading) {
      return () => null;
    }
    const infoData = getMenuData(route?.routes || [], menu, intl.formatMessage, menuDataRender);
    // 稍微慢一点 render，不然会造成性能问题，看起来像是菜单的卡顿
    const animationFrameId = requestAnimationFrame(() => {
      setMenuInfoData(infoData);
    });
    return () => window.cancelAnimationFrame && window.cancelAnimationFrame(animationFrameId);
  }, [props.route, stringify(menu)]);

  const iconScriptUrl = '//at.alicdn.com/t/font_8d5l8fzk5b87iudi.js';
  const [myCollapsed, setCollapsed] = React.useState(false);

  // const columnFixed = document.getElementById('root');
  // console.log(columnFixed);
  // if (columnFixed) {
  //   let offsetTop = columnFixed.offsetTop;
  //   console.log(offsetTop);
  // }

  return (
    <div style={{ display: 'flex', flexDirection: 'row', minHeight: '100%' }}>
      <div
        style={
          myCollapsed
            ? { display: 'none' }
            : { backgroundColor: 'red', width: 64 + 130, display: 'flex', flexDirection: 'row' }
        }
      >
        <div style={{ display: 'flex', flexDirection: 'row' }}>
          <div style={{ background: '#444', width: 64 }}>
            <MainSider
              matchMenuKeys={matchMenuKeys}
              menuData={menuData}
              iconScriptUrl={iconScriptUrl}
            />
          </div>
          <div style={{ background: '#fff', width: 130 }}>
            <SubSider
              matchMenuKeys={matchMenuKeys}
              menuData={menuData}
              iconScriptUrl={iconScriptUrl}
            />
          </div>
        </div>
      </div>
      <Layout>
        <HeadderContent
          matchMenuKeys={matchMenuKeys}
          breadcrumbMap={breadcrumbMap}
          collapsed={myCollapsed}
          onCollapseClick={setCollapsed}
        >
          <RightContent />
        </HeadderContent>
        <Content>{children}</Content>
        <Footer>
          <MyFooter />
        </Footer>
      </Layout>
    </div>
  );
};

export default BasicLayout;
